//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Expressions;

namespace OpenLS.Spreadsheet.Parsing
{
#if DEBUG
    [ContractClass(typeof(RangeFactoryContract))]
#endif
    abstract class RangeFactory
    {
        protected RangeFactory(Worksheet caller)
        {
            _caller = caller;
        }

        private readonly Worksheet _caller;

        public static RangeFactory Create(RangeFactory factory, Worksheet worksheet,  CellReferenceMode cellReferenceMode)
        {
            if (factory != null)
                return factory;
            if (worksheet == null)
                return null;
            return new SingleWorksheetRangeFactory(worksheet, worksheet, cellReferenceMode);
        }


        public abstract Worksheet Worksheet { get; }

        public Worksheet Caller
        {
            get { return _caller; }
        }


        internal abstract RangeReference GetRangeReference(ReferenceToken token);
        internal RangeReference GetRangeReference(RangeReferenceInfo rInfo)
        {
            if (rInfo == null)
                return null;
            return GetRangeReferenceImp(rInfo);
        }

        protected abstract RangeReference GetRangeReferenceImp(RangeReferenceInfo rInfo);
        public abstract Expression GetCellReferenceExpression(CellReferenceToken token);
        public abstract CellEnumeratorExpression GetAnyReferenceExpression(ReferenceToken token1);

        public abstract Expression GetRangeReferenceExpression(List<ReferenceToken> tokens);
    }
#if DEBUG
    [ContractClassFor(typeof(RangeFactory))]
    abstract class RangeFactoryContract : RangeFactory
    {
        protected RangeFactoryContract(Worksheet caller)
            : base(caller)
        {
        }
        public override Expression GetRangeReferenceExpression(List<ReferenceToken> tokens)
        {
            Contract.Requires(tokens != null);
            Contract.Requires(tokens.Count > 0);
            return default(Expression);
        }
        public override Expression GetCellReferenceExpression(CellReferenceToken token)
        {
            Contract.Requires(token != null);
            throw new System.NotImplementedException();
        }
    }
#endif
}
